package xyj.sparrow.scheduler.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import xyj.sparrow.scheduler.annotation.UserValid;
import xyj.sparrow.scheduler.common.Result;
import xyj.sparrow.scheduler.cron.Cron;
import xyj.sparrow.scheduler.cron.ops.CronOps;
import xyj.sparrow.scheduler.cron.thread.MonitorThread;
import xyj.sparrow.scheduler.entity.App;
import xyj.sparrow.scheduler.entity.Task;
import xyj.sparrow.scheduler.service.IAppService;
import xyj.sparrow.scheduler.service.ITaskService;
import xyj.sparrow.scheduler.util.CronUtil;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author jim
 * @since 2021-06-05
 */
@RestController
@RequestMapping("/api/v1/task")
@CrossOrigin
@Slf4j
public class TaskController {
    @Resource
    private ITaskService iTaskService;
    @Resource
    private MonitorThread monitorThread;
    @Resource
    private IAppService iAppService;
    @Resource
    private CronOps cronOps;

    @PostMapping("/list")
    @UserValid
    public Result<IPage<Task>> listTask(@RequestBody Page<Task> iPage) {
        if (iPage == null) {
            iPage = new Page<>();
        }
        QueryWrapper<Task> query = new QueryWrapper<>();
        if (!iPage.getRecords().isEmpty()) {
            Task task = iPage.getRecords().get(0);
            if (!StrUtil.isBlank(task.getTaskName())) {
                query.like("task_name", task.getTaskName());
            }
        }
        IPage<Task> page = iTaskService.page(iPage, query);
        return Result.success(page);
    }

    @PostMapping("")
    public Result<Task> addTask(@RequestBody Task task) {
        task.setCreateTime(LocalDateTime.now());
        task.setUpdateTime(LocalDateTime.now());
        iTaskService.save(task);
        if (task.getTaskStatus() == 1) {
            App app = iAppService.getById(task.getAppId());
            if (app.getAppStatus() == 1) {
                cronOps.addCron(new Cron(monitorThread, task));
            }
        }
        return Result.success(task);
    }

    @PutMapping("")
    public Result<Object> updateTask(@RequestBody Task task) {
        task.setUpdateTime(LocalDateTime.now());
        iTaskService.updateById(task);
        if (task.getTaskStatus() == 1) {
            App app = iAppService.getById(task.getAppId());
            if (app.getAppStatus() == 1) {
                cronOps.updateCron(new Cron(monitorThread, task));
            } else {
                cronOps.removeByTaskIds(Collections.singletonList(task.getTaskId()));
            }
        } else {
            cronOps.removeByTaskIds(Collections.singletonList(task.getTaskId()));

        }
        return Result.success();
    }

    @DeleteMapping("/{taskId}")
    public Result<Object> deleteTask(@PathVariable("taskId") String taskId) {
        iTaskService.removeById(taskId);
        cronOps.removeByTaskIds(Collections.singletonList(taskId));
        return Result.success();
    }

    @DeleteMapping("/")
    @UserValid
    public Result<Object> batchDeleteApp(@RequestBody List<String> ids) {
        iTaskService.removeByIds(ids);
        cronOps.removeByTaskIds(ids);
        return Result.success();
    }

    @PostMapping("/verify")
    @UserValid
    public Result<Boolean> verify(@RequestBody Map<String, String> cronStr) {
        boolean verify = CronUtil.verify(cronStr.get("cron"));
        return Result.success(verify);
    }

    @PutMapping("/{ops}")
    @UserValid
    public Result<Object> batchOpsApp(@RequestBody List<String> ids, @PathVariable("ops") String ops) {
        UpdateWrapper<Task> updateWrapper = new UpdateWrapper<>();
        if ("enabled".equals(ops)) {
            updateWrapper.set("task_status", 1);
            updateWrapper.in("task_id", ids);
            iTaskService.update(updateWrapper);
            cronOps.batchUpdateCronByTask(ids);
        } else {
            //批量禁用app
            updateWrapper.set("task_status", 0);
            updateWrapper.in("task_id", ids);
            iTaskService.update(updateWrapper);
            cronOps.removeByTaskIds(ids);
        }

        return Result.success();
    }

    @PostMapping("/{taskId}")
    public Result<Object> runTask(@PathVariable("taskId") String taskId) {
        cronOps.runCronByTask(taskId);
        return Result.success();
    }
}

